package com.x52im.rainbowchat.http.logic.pay.alipay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserCertdocCertverifyConsultRequest;
import com.alipay.api.request.AlipayUserCertdocCertverifyPreconsultRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserCertdocCertverifyConsultResponse;
import com.alipay.api.response.AlipayUserCertdocCertverifyPreconsultResponse;
import com.eva.framework.dbpool.DBShell;
import com.x52im.rainbowchat.BaseConf;
import com.x52im.rainbowchat.http.logic.dto.AlipayCertverifyDTO;
import okhttp3.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Vector;

public class MCertverify {
    DBShell db = new DBShell();

    /**
     * 第一步：录入用户实名信息
     *
     * @param dto
     * @return
     * @throws AlipayApiException
     */
    public String getVerifyId(AlipayCertverifyDTO dto) throws Exception {
        AlipayUserCertdocCertverifyPreconsultRequest request = new AlipayUserCertdocCertverifyPreconsultRequest();
        String bizContent = String.format("{'user_name':'%s', 'cert_no':'%s', 'cert_type':'IDENTITY_CARD'}", dto.getUserName(), dto.getCertNo());
        request.setBizContent(bizContent);
        AlipayUserCertdocCertverifyPreconsultResponse response = AlipayClientTools.alipayClient.certificateExecute(request);
        if (response.isSuccess()) {
            dto.setVerifyId(response.getVerifyId());
        }
        dto.setcBizReqXml(JSON.toJSONString(request));
        dto.setcBizRespXml(JSON.toJSONString(response));

        String sql = "INSERT INTO alipay_certverify " +
                "(user_uid, user_name, cert_no, cert_type, mobile, logon_id, ext_info, verify_id, c_biz_req_xml, c_biz_resp_xml, c_biz_resp_date) " +
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now())";
        boolean b = db.update(sql, new Object[]{
                dto.getUserUid(),
                dto.getUserName(),
                dto.getCertNo(),
                dto.getCertType(),
                dto.getMobile(),
                dto.getLogonId(),
                dto.getExtInfo(),
                dto.getVerifyId(),
                dto.getcBizReqXml(),
                dto.getcBizRespXml()}, true);

        return dto.getcBizRespXml();
    }

    /**
     * 第二步：获取唤起支付宝授权的字符串
     *
     * @param dto
     * @return
     */
    public String getAuthStr(AlipayCertverifyDTO dto) throws UnsupportedEncodingException {
        StringBuffer authStr = new StringBuffer();
        authStr.append("apiname=").append("com.alipay.account.auth").append("&");
        authStr.append("method=").append("alipay.open.auth.sdk.code.get").append("&");
        authStr.append("app_id=").append(BaseConf.getInstance().getAPP_ID()).append("&");
        authStr.append("app_name=").append("mc").append("&");
        authStr.append("biz_type=").append("openservice").append("&");
        authStr.append("pid=").append(BaseConf.getInstance().getAPP_ALIPAY_USER_ID()).append("&");
        authStr.append("product_id=").append("APP_FAST_LOGIN").append("&");
        authStr.append("scope=").append("id_verify").append("&");
        authStr.append("target_id=").append(AlipayClientTools.getTargetId(String.valueOf(dto.getUserUid()))).append("&");
        authStr.append("auth_type=").append("AUTHACCOUNT").append("&");
        authStr.append("sign_type=").append("RSA2").append("&");

        String sign = URLEncoder.encode(authStr.toString(), "UTF-8");
        authStr.append("sign=").append(sign);

        return authStr.toString();
    }

    /**
     * 第三步：获取accessToken<br>
     * 正式环境:移动端传authCode过来<br>
     * 测试环境:调用getAuthCodeByURL暂时网页获取authCode,通过回调MCertverifyRedirect<br>
     *
     * @param dto
     * @param isSC
     * @return
     * @throws AlipayApiException
     */
    public String getAccessTokenByAuthCode(AlipayCertverifyDTO dto, boolean isSC) throws Exception {
        if (!isSC) {
            String sql = String.format("select id, user_uid from alipay_certverify where verify_id='%s' order by id desc", dto.getVerifyId());
            String[] queryResult = db.querySingleRowItems(sql);
            dto.setId(Integer.parseInt(queryResult[0]));
            dto.setUserUid(Integer.parseInt(queryResult[1]));
        }

        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(dto.getAuthCode());
        request.setGrantType("authorization_code");
        AlipaySystemOauthTokenResponse response = AlipayClientTools.alipayClient.certificateExecute(request);
        dto.setcGrantReqXml(JSON.toJSONString(request));
        dto.setcGrantRespXml(JSON.toJSONString(response));
        dto.setAlipayUserId(response.getUserId());
        dto.setAccessToken(response.getAccessToken());

        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        String sql1 = "UPDATE alipay_certverify " +
                "SET alipay_user_id=?, auth_code=?, access_token=?, c_grant_req_xml=?, c_grant_resp_xml=?, c_grant_resp_date=now(), target_id=? " +
                "WHERE verify_id=?";
        sqls.add(sql1);
        values.add(new Object[]{
                dto.getAlipayUserId(),
                dto.getAuthCode(),
                dto.getAccessToken(),
                dto.getcGrantReqXml(),
                dto.getcGrantRespXml(),
                dto.getTargetId(),
                dto.getVerifyId()});

        String sql2 = "UPDATE missu_account SET alipay_user_id=? WHERE user_uid=?";
        sqls.add(sql2);
        values.add(new Object[]{dto.getAlipayUserId(), dto.getUserUid()});

        boolean b = db.update(sqls, values, true);

        return JSON.toJSONString(response);
    }

    /**
     * 发送授权码请求,通过回调MCertverifyRedirect获取授权码<br>
     * 没有移动端配合前先用这个方式
     *
     * @param dto
     * @return
     * @throws IOException
     */
    @Deprecated
    public String getAuthCodeByURL(AlipayCertverifyDTO dto) throws IOException {
        String appId = BaseConf.getInstance().getAPP_ID();
        String redirectURI = URLEncoder.encode(BaseConf.getInstance().getALI_CERT_REDIRECT_URL(), "UTF-8");
        String furl = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=id_verify&redirect_uri=%s&cert_verify_id=%s";
        String url = String.format(furl, appId, redirectURI, dto.getVerifyId());
        System.out.println(url);
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new okhttp3.Request.Builder().url(url).get().build();
        Response response = okHttpClient.newCall(request).execute();
        String str = response.body().string();
        return str;
    }

    /**
     * 第四步：实名信息校验
     *
     * @param dto
     * @return
     * @throws AlipayApiException
     */
    public String cert(AlipayCertverifyDTO dto) throws Exception {
        AlipayUserCertdocCertverifyConsultRequest request = new AlipayUserCertdocCertverifyConsultRequest();
        String bizContent = String.format("{'verify_id':'%s'}", dto.getVerifyId());
        request.setBizContent(bizContent);
        AlipayUserCertdocCertverifyConsultResponse response = AlipayClientTools.alipayClient.certificateExecute(request, dto.getAccessToken());
        dto.setcCertReqXml(JSON.toJSONString(request));
        dto.setcCertRespXml(JSON.toJSONString(response));

        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        String sql1 = "UPDATE alipay_certverify " +
                "SET c_cert_req_xml=?, c_cert_resp_xml=?, c_cert_resp_date=now(), c_cert_resp_code=?,c_cert_resp_msg=?,c_cert_resp_passed=? " +
                "WHERE verify_id=?";
        sqls.add(sql1);
        values.add(new Object[]{
                dto.getcCertReqXml(),
                dto.getcCertRespXml(),
                response.getCode(),
                response.getMsg(),
                response.getPassed(),
                dto.getVerifyId()});

        String sql2 = "UPDATE missu_users SET is_realname=? WHERE user_uid=?";
        values.add(new Object[]{response.getPassed(), dto.getUserUid()});
        sqls.add(sql2);

        boolean b = db.update(sqls, values, true);

        return dto.getcCertRespXml();

    }
}
